/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.blue.annotation;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 *
 * @author kelvio
 */
class ReflectionFacade {
    
    /**
     * 
     * @param field
     * @param instance
     * @return 
     */
    public static Object getDirect(String field, Object instance) {
        try {
            Field f = findField(field, instance.getClass());
            f.setAccessible(true);
            return f.get(instance);
            
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        
    }
    
    public static void setDirect(Field field, Object instance, Object value) {
        try {
            field.setAccessible(true);
            field.set(instance, value);            
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    /**
     * 
     * @param field
     * @param instance
     * @param value 
     */
    public static void setDirect(String field, Object instance, Object value) {
        try {
            setDirect(findField(field, instance.getClass()), instance, value);            
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    /**
     * Gets all fields of the specified class,
     * that can have public, protected, private and default access.
     * The field set contains all fields declared by the class and all
     * the subclass.
     * @param clazz
     * @return 
     */
    public static Set<Field> getAllFields(Class<?> clazz) {
        Set<Field> fields = new HashSet<Field>();
        
        //Gets the local fields (fields declared by class) first 
        Field[] localFields = clazz.getDeclaredFields();
        fields.addAll(Arrays.asList(localFields));
                        
        //Gets all fields of the superclasses
        if (clazz.getSuperclass() != null) {            
            fields.addAll(ReflectionFacade.getAllFields(clazz.getSuperclass()));        
        }
        
        return fields;
    }
    
    public static Field findField(String name, Class clazz) {        
        try {
            return  clazz.getDeclaredField(name);            
        } catch (Exception e) {
            if (clazz.getSuperclass() != null) {
                return findField(name, clazz.getSuperclass());
            }
        }        
       throw new RuntimeException("No such field:" + name);
    }
      
}
